package com.zto.sch.advance.redis;

import java.util.Map;

/**
 * @program: sch-diy-parent
 * @description:
 * @author: sch
 * @create: 2021-01-19 10:45
 **/
public class LRUMyCache {
    private int capacity;
    //保存链表的头节点和尾节点
    private Node first;
    private Node last;

    class Node {
        String key;
        Object value;

        Node pre;
        Node next;
    }

    private Map<String, Node> map;

    public LRUMyCache(int capacity) {
        this.capacity = capacity;
    }

    public Object getCache(String key) {
        Node node = map.get(key);

        //为空返回-1
        if (node == null) {
            return -1;
        }

        //移动链表
        moveToHead(node);
        return node.value;
    }

    private void moveToHead(Node node) {
        if (node == first) {
            return;
        } else if (node == last) {
            last.pre.next = null;
            last = last.pre;
        } else {
            node.pre.next = node.next;
            node.next.pre = node.pre;
        }

        node.pre = first.pre;
        node.next = first;
        first.pre = node;
        first = node;
    }


    public void put(String key, Object vale) {
        Node node = map.get(key);
        if (node == null) {
            node = new Node();
            node.key = key;
            node.value = vale;

            if (map.size() == capacity) {
                removeLast();
            }

            addToHead(node);
            map.put(key, node);
        } else {
            node.value = vale;
            moveToHead(node);
        }

    }

    private void addToHead(Node node) {
        if (map.isEmpty()) {
            first = node;
            last = node;
        } else {
            node.next = first;
            first.pre = node;
            first = node;
        }
    }

    private void removeLast() {
        map.remove(last.key);
        Node prevNode = last.pre;
        if (prevNode != null) {
            prevNode.next = null;
            last = prevNode;
        }
    }


    public static void main(String[] args) {
        LRUCache cache = new LRUCache(3);
        cache.put("a", "哈哈1");
        cache.put("b", "哈哈2");
        cache.put("c", "哈哈3");
        cache.get("a");
        cache.put("d", "哈哈4");
        System.out.println(cache);
    }
}
